package com.zhoug.common.utils;

import android.telephony.PhoneNumberUtils;
import android.util.Log;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串工具包
 */
public class StringUtils {
    private static final String TAG = ">>>StringUtils";
    /**
     * 全角空格，长度等于一个中文字符
     *
     */
    public static final String BLANK_SPACE_2 = "&#8195;";
    /**
     * 全角空格，长度等于半个中文字符
     */
    public static final String BLANK_SPACE_1 = "&#8194;";
    /**
     * 不会被合并的空格，长度与常规空格相同
     */
    public static final String BLANK_SPACE = "&#160;";
    /**
     * 长度等于一个中文字符
     */
    private static final String BLANK_SPACE_3="\u3000";
    /**
     * 长度等于1/4中文字符
     */
    private static final String BLANK_SPACE_4="\u0020";

    /**
     * 中文unicode开始编码
     */
    private static final char CHINESE_UNICODE_START = '\u4E00';
    /**
     * 中文unicode结束编码
     */
    private static final char CHINESE_UNICODE_END = '\u9FA5';

    /**
     * email的正则表达式
     */
    private final static String PATTERN_EMAIL = "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";

    /**
     * 经度的正则表达式:错误
     */
    private final static String PATTERN_LATITUDE = "/^[\\-\\+]?(0(\\.\\d{1,10})?|([1-9](\\d)?)(\\.\\d{1,10})?|1[0-7]\\d{1}(\\.\\d{1,10})?|180\\.0{1,10})$/";

    /**
     * 维度的正则表达式:错误
     */
    private final static String PATTERN_LONGITUDE = "/^(\\-|\\+)?([0-8]?\\d{1}\\.\\d{0,6}|90\\.0{0,6}|[0-8]?\\d{1}|90)$/";

    private static Matcher MATCHER_NUMBER;

    /**
     * 断给定字符串是否空白串
     * null、"null"、" "
     *
     * @param str
     * @return
     */
    public static boolean isNullOrEmpty(Object str) {
        if (str == null || "".equals(str.toString().trim()) || "null".equalsIgnoreCase(str.toString()))
            return true;
        return false;
    }

    /**
     * 判断是不是一个合法的电子邮件地址
     *
     * @param email
     * @return
     */
    public static boolean isEmail(String email) {

        return !isNullOrEmpty(email) && Pattern.compile(PATTERN_EMAIL).matcher(email).matches();
    }

    /**
     * 返回字符串值 null返回空""
     *
     * @param str
     * @return
     */
    public static String getText(String str) {
        return isNullOrEmpty(str) ? "" : str;
    }

    /**
     * 返回字符串值 空返回空null
     *
     * @param str
     * @return
     */
    public static String getTextNull(String str) {
        return isNullOrEmpty(str) ? null : str;
    }

    /**
     * 是否是手机电话
     *
     * @param phone 手机号码 11位
     * @return
     */
    public static boolean isMobilePhoneCode(String phone) {
        if (isNullOrEmpty(phone)) {
            return false;
        }
        //匹配手机号码
        Pattern pattern = Pattern.compile("^[1][3,4,5,6,7,8,9][0-9]{9}$"); // 验证手机号
        return pattern.matcher(phone).matches();
    }

    /**
     * 判断是否为座机号码
     *
     * @param phone
     * @return
     */
    public static boolean isFixedPhoneCode(String phone) {
        if (isNullOrEmpty(phone)) {
            return false;
        }
        boolean isPhone;
        // 验证带区号的
        if (phone.length() > 9) {
            Pattern p1 = Pattern.compile("^[0][0-9]{2,3}[0-9]{4,8}$");
            isPhone = p1.matcher(phone).matches();
        } else {
            // 验证没有区号的
            Pattern p2 = Pattern.compile("\\d{4,8}");
            isPhone = p2.matcher(phone).matches();
        }

        return isPhone;

    }

    /**
     * 验证是否为电话号码包括手机和座机
     *
     * @param phone
     * @return
     */
    public static boolean isPhoneCode(String phone) {
        return isMobilePhoneCode(phone) || isFixedPhoneCode(phone);
    }

    /**
     * 判断是否为电话号码 原生方法
     * @param phone
     * @return
     */
    public static boolean isGlobalPhoneNumber(String phone) {
        return PhoneNumberUtils.isGlobalPhoneNumber(phone);
    }

    /**
     * 判断是否为身份证
     * @param idCard 身份证号
     * @return
     */
    public static boolean isIdCard(String idCard) {
        if (isNullOrEmpty(idCard)) {
            return false;
        }

        Pattern pattern = Pattern.compile("\\d{17}[0-9Xx]");
        if (!pattern.matcher(idCard).matches()) {
            return false;
        }
        //验证出生日期
        if (idCard.trim().length() == 18) {
            String date = idCard.trim().substring(6, 14);//7-14为表示出生日期
            SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
            try {
                Date parse = format.parse(date);//把给定的日期字符串转化为日期格式
                String newDate = format.format(parse);//再把日期转化为字符串
                //原字符串和转化的字符串相等则日期合法
                //例：date=19860532 那么newDate=19860601
                if (date.equals(newDate)) {
                    return true;
                }
            } catch (ParseException e) {
                e.printStackTrace();
                System.out.println("日期不合法");
            }
        }
        return false;
    }

    public static String getBirthdayByIdCard(String idCard) {
        //验证出生日期
        if (idCard.length() == 18) {
            //7-14为表示出生日期
            String year = idCard.substring(6, 10);
            String month = idCard.substring(10, 12);
            String day = idCard.substring(12, 14);
            return year + "-" + month + "-" + day;

        }

        return null;
    }

    /**
     * 根据合法的身份证获取性别
     *
     * @param idCard
     * @return 性别
     */
    public static String getSexByIdCard(String idCard) {
        if (isIdCard(idCard)) {
            int gd = Integer.parseInt(idCard.charAt(16) + "");
            if (gd % 2 == 0) {//偶数
                return "女";
            } else {
                return "男";
            }
        } else {
            throw new IllegalArgumentException("身份证号码不合法");
        }
    }

    /**
     * 把字符串用URLEncoder编码 返回可以用url请求的字符串
     * 空格转化为"%20"
     *
     * @param s       带中文的字符串
     * @param charset 编码 默认utf-8
     * @return
     */
    public static String urlEncodeCH(String s, String charset) {
        if (isNullOrEmpty(s)) {
            return null;
        }
        if (charset == null) {
            charset = "utf-8";
        }
        String result = "";
        String[] array = s.split("");
        for (int i = 0; i < array.length; i++) {
            try {
                int length = array[i].getBytes(charset).length;
                if (length >= 2) {
                    String encode = URLEncoder.encode(array[i], charset);
                    result += encode;
                } else {
                    result += array[i];
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }

        return result.replaceAll(" ", "%20");
    }

    /**
     * 把给定的时间(单位秒)转化成 00:00的格式
     *
     * @param seconds
     * @return
     */
    public static String getStringTime(long seconds) {
        if (seconds <= 0) {
            return "00:00";
        } else if (seconds < 10) {
            return "00:0" + seconds;
        } else if (seconds < 60) {
            return "00:" + seconds;
        } else {
            String s = "";
            long mm = seconds / 60;//分钟
            long ss = seconds % 60;//秒
            if (mm < 10) {
                s += "0" + mm + ":";
            } else {
                s += mm + ":";
            }
            if (ss < 10) {
                s += "0" + ss;
            } else {
                s += ss;
            }
            return s;
        }

    }

    /**
     * 字符串格式化
     * 占位符:
     * 转换符    详细说明         示例
     * %s	字符串类型	        "简书"
     * %c	字符类型	            'm'
     * %b	布尔类型        	    true
     * %d	整数类型（十进制）	88
     * %x	整数类型（十六进制）	FF
     * %o	整数类型（八进制）	77
     * %f	浮点类型	          8.888      %2f 保留2位小数
     * %a	十六进制浮点类型	    FF.35AE
     * %e	指数类型	            9.38e + 5
     * %%	百分比类型	        %（%特殊字符%%才能显示%）
     *
     * @param format 需要格式化的字符串 eg: 阅读%d次
     * @param args   占位符的值 eg:2
     * @return
     */
    public static String format(String format, Object... args) {
        return String.format(Locale.CANADA,format, args);
    }

    /**
     * 判断字符串是否是boolean
     *
     * @param s
     * @return
     */
    public static boolean isBoolean(String s) {
        if ("true".equals(s) || "false".equals(s)) {
            return true;
        }
        return false;
    }

    /**
     * 判断字符串是否是数字
     *
     * @param s
     * @return
     */
    public static boolean isNumber(String s) {
        //matches()是全部匹配，是将整个输入串与模式匹配，
        _getNumberMatch().reset(s);
        return MATCHER_NUMBER.matches();
    }



    private static Matcher _getNumberMatch() {
        if (MATCHER_NUMBER == null) {
            MATCHER_NUMBER = Pattern.compile("[0-9]+").matcher("");
        }
        return MATCHER_NUMBER;
    }

    /**
     * 是否是纬度
     *
     * @return
     */
    public static boolean isLatitude(String latitude) {
        return Pattern.compile(PATTERN_LATITUDE).matcher(latitude).matches();
    }

    /**
     * 是否是经度
     *
     * @return
     */
    public static boolean isLongitude(String longitude) {
        return Pattern.compile(PATTERN_LONGITUDE).matcher(longitude).matches();

    }

    /**
     * 数字大于1万以上单单位
     * @param number
     * @return eg:6500,1.6万,2890万
     */
    public static String getNumberFormat(int number){
        if(number<10000){
            return number+"";
        }
        return MathUtils.getDecimal((double) number/10000,2)+"万";
    }

    /**
     * a,b是否相对
     * @param a
     * @param b
     * @return
     */
    public static boolean equals(Object a,Object b){
        return Objects.equals(a, b);
    }

    /**
     * a,b是否相对
     * @param a
     * @param b
     * @return
     */
    public static boolean equalsIgnoreCase(String a,String b){
        return a != null && a.equalsIgnoreCase(b);
    }

    /**
     * 字节数组转16进制字符串
     * @param array 字节数组
     * @return
     */
    public static String bytes2HexString(byte[] array) {
        StringBuilder builder = new StringBuilder();
        for (byte b : array) {
            //b&0xFF :  为什么要&0xFF
            //byte=8bit b&0xFF 就是只取低八位
            String hex = Integer.toHexString(b & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            builder.append(hex);
        }

        return builder.toString().toUpperCase();
    }

    /**
     * 数字格式化 eg:15218961->1,521万
     *
     * @param number
     * @return
     */
    public static String formatNumber(long number) {
        if (Math.abs(number) < 10000) {
            return String.valueOf(number);
        }
        boolean isNegative = number < 0;//负数
        if (isNegative) {
            number = -number;
        }
        String value = String.valueOf(number / 10000);
        int length = value.length();
        if (length < 4) {
            if (isNegative) {
                return "-" + value + "万";
            } else {
                return value + "万";
            }
        } else {
            StringBuilder stringBuilder = new StringBuilder(value);
            for (int i = stringBuilder.length() - 3; i > 0; i -= 3) {
                stringBuilder.insert(i, ',');
            }
            if (isNegative) {
                return "-" + stringBuilder.toString() + "万";
            } else {
                return stringBuilder.toString() + "万";
            }
        }
    }

    /**
     * 升序排序
     * @param str1
     * @param str2
     * @return
     */
    public static int compareTo(String str1,String str2){
        if(StringUtils.isNullOrEmpty(str1) && StringUtils.isNullOrEmpty(str2)){
            return 0;
        }else  if(StringUtils.isNullOrEmpty(str1)){
            return 1;
        }else  if(StringUtils.isNullOrEmpty(str2)){
            return -1;
        }else{
            return str1.compareTo(str2);
        }
    }

    /**
     * 更具指定的单词分组
     * eg:
     * text=上的我放上的大上是的是放上的大非上的,
     * words=["是","上的"]
     * =>["上的","我放","上的","大上","是","的","是","放","上的","大非","上的"]
     * @param text 字符串
     * @param words 分组单词
     * @param wordIndex 用words中的哪个单词分组,传0
     * @param result 结果
     */
    public static List<String> groupByWords(String text,String[] words, int wordIndex, List<String> result) {
        String s = words[wordIndex];
        int nextWordIndex=wordIndex+1;
        Log.d(TAG, "groupByWords:result="+JsonUtils.toJson(result));

        if(text.startsWith(s)){
            result.add(s);
            text=text.substring(s.length());
        }
        Log.d(TAG, "groupByWords:wordIndex="+wordIndex+",word="+s+",text="+text);
        String[] split = text.split(s);
        Log.d(TAG, "groupByWords:split="+JsonUtils.toJson(split));
        if (split.length == 1) {
           if(!"".equals(split[0])){
               if (nextWordIndex < words.length) {
                   groupByWords(split[0], words, nextWordIndex, result);
               }else{
                   result.add(split[0]);
               }
           }
        } else {
            for (int i = 0; i < split.length; i++) {
                String group = split[i];
                if(!"".equals(group)){
                    if (nextWordIndex < words.length) {
                        groupByWords(group, words,nextWordIndex, result);
                    }else{
                        result.add(group);
                    }
                    if (i < split.length - 1 || text.endsWith(s)) {
                        result.add(s);
                    }
                }

            }
        }
        return result;
    }


    /**
     * 文本的后面一半用"*"替换
     * @param text
     * @return showTextBeforeHalf
     */
    private static String replaceAfterHalfWithStar(String text) {
        if (StringUtils.isNullOrEmpty(text)) return null;
        if (text.length() <= 1) {
            return text;
        } else {
            int index = text.length() / 2;
            String result = text.substring(0, index);
            for (int i = index; i < text.length(); i++) {
                result += "*";
            }
            return result;
        }
    }

    /**
     * 是否是中文
     *
     * @param c
     * @return
     */
    public static boolean isChinese(char c) {
        if (c >= CHINESE_UNICODE_START && c <= CHINESE_UNICODE_END) {
            return true;
        }
        return false;
        //CJK_UNIFIED_IDEOGRAPHS “中日韩统一象形文字”Unicode字符块的常量。
        //CJK_COMPATIBILITY_IDEOGRAPHS “中日韩兼容象形文字”Unicode字符块的常量
        //CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A “中日韩统一象形文字扩展A”Unicode字符块的常量。
        /*Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
        ) {
            return true;
        }
        return false;*/
    }

    /**
     * 判断给定的字符串是否全是中文
     * @param charSequence
     * @return
     */
    public static boolean isAllChinese(CharSequence charSequence){
        if(charSequence!=null && charSequence.length()>0){
            boolean result=true;
            for (int i = 0; i < charSequence.length(); i++) {
                char c = charSequence.charAt(i);
                if (!isChinese(c)) {
                    result=false;
                    break;
                }
            }
            return result;
        }
        return false;
    }

    /**
     * 是否是空白字
     * @param ch
     * @return
     */
    public static boolean isWhitespace(char ch) {
        return Character.isWhitespace(ch);
    }


    /**
     * 对齐 插入空格
     * @param name
     * @return
     */
    public static String getAlignName(String name,int alignEms) {
        if (alignEms > 1 && name != null && name.length() < alignEms) {
            int nameLength = name.length();
            //需要插入的中文空格数量
            int insetCount = alignEms - nameLength;
            //文字间隔
            int nameInterval = nameLength - 1;
            //每个间隔需要插入的空格数
            float space = insetCount * 1.0f / nameInterval;
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < nameLength - 1; i++) {
                builder.append(name.charAt(i));
                if (space > 1) {
                    for (int j = 0; j < space; j++) {
                        builder.append("\u3000");
                    }
                } else if (space == 1f) {
                    builder.append("\u3000");
                } else if (space == 0.5f) {
                    builder.append("\u0020\u0020");
                } else if (space == 0.25f) {
                    builder.append("\u0020");
                }
            }
            builder.append(name.charAt(nameLength - 1));
            return builder.toString();
        }
        return name;
    }

    /**
     * 在一个字符串里面统计给定字符串的个数
     * @param str
     * @param regex
     * @return
     */
    public static int countString(String str,String regex){
        //str为原字符串,regex为给定字符串
        int index=str.indexOf(regex);
        //第一次找原来字符串有没有给定字符串,如果为-1(代表没有),那就没有必要往后去找了,如果有就进入循环去找
        int count=0;
        while (index!=-1){
            //进入循环就count+1
            count++;
            //每弄一次都需要截取+获取截取后子串中给定字符串的位置
            str=str.substring(index+regex.length());
            //indexOf默认还是从0开始,只不过是从字符串的第一位开始而已
            index=str.indexOf(regex);
        }
        return  count;
    }

}
